package handlers

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"sysu-giep/internal/database/models"
	"sysu-giep/internal/service"
	"sysu-giep/pkg/logger"
	"sysu-giep/pkg/response"

	"github.com/gin-gonic/gin"
)

// PrivateChatHandler 私聊处理器
type PrivateChatHandler struct {
	chatService *service.PrivateChatService
}

// NewPrivateChatHandler 创建私聊处理器
func NewPrivateChatHandler(chatService *service.PrivateChatService) *PrivateChatHandler {
	return &PrivateChatHandler{
		chatService: chatService,
	}
}

// SendMessageRequest 发送消息请求
type SendMessageRequest struct {
	Content   string             `json:"content" binding:"required,min=1,max=2000"`
	Type      models.MessageType `json:"type" binding:"required,oneof=text image file system"`
	ReplyToID *uint              `json:"reply_to_id,omitempty"`
	FileURL   string             `json:"file_url,omitempty" maxLength:"255"`
	FileName  string             `json:"file_name,omitempty" maxLength:"255"`
	FileSize  *int64             `json:"file_size,omitempty"`
}

// GetChats 获取私聊会话列表
func (h *PrivateChatHandler) GetChats(c *gin.Context) {
	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 获取查询参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(c.DefaultQuery("size", "10"))

	// 获取私聊会话列表
	chats, total, err := h.chatService.GetUserChats(userID.(uint), page, size)
	if err != nil {
		logger.Error(fmt.Errorf("获取私聊会话列表失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "获取私聊会话列表失败")
		return
	}

	response.Success(c, gin.H{
		"chats": chats,
		"pagination": gin.H{
			"page":  page,
			"size":  size,
			"total": total,
		},
	})
}

// GetChat 获取私聊会话详情
func (h *PrivateChatHandler) GetChat(c *gin.Context) {
	// 获取聊天对象ID
	partnerID, err := strconv.ParseUint(c.Param("partner_id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "用户ID格式错误")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 获取私聊会话
	chat, err := h.chatService.GetOrCreateChat(userID.(uint), uint(partnerID))
	if err != nil {
		logger.Error(fmt.Errorf("获取私聊会话失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "获取私聊会话失败")
		return
	}

	response.Success(c, chat)
}

// GetMessages 获取私聊消息
func (h *PrivateChatHandler) GetMessages(c *gin.Context) {
	// 获取聊天对象ID
	partnerID, err := strconv.ParseUint(c.Param("partner_id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "用户ID格式错误")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 获取查询参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
	before := c.Query("before") // 获取此时间之前的消息
	after := c.Query("after")   // 获取此时间之后的消息

	// 解析时间参数
	var beforeTime, afterTime *time.Time
	if before != "" {
		if t, err := time.Parse(time.RFC3339, before); err == nil {
			beforeTime = &t
		}
	}
	if after != "" {
		if t, err := time.Parse(time.RFC3339, after); err == nil {
			afterTime = &t
		}
	}

	// 获取私聊消息
	messages, total, err := h.chatService.GetChatMessages(
		userID.(uint),
		uint(partnerID),
		page,
		size,
		beforeTime,
		afterTime,
	)
	if err != nil {
		logger.Error(fmt.Errorf("获取私聊消息失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "获取私聊消息失败")
		return
	}

	response.Success(c, gin.H{
		"messages": messages,
		"pagination": gin.H{
			"page":  page,
			"size":  size,
			"total": total,
		},
	})
}

// SendMessage 发送私聊消息
func (h *PrivateChatHandler) SendMessage(c *gin.Context) {
	// 获取聊天对象ID
	partnerID, err := strconv.ParseUint(c.Param("partner_id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "用户ID格式错误")
		return
	}

	var req SendMessageRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error(fmt.Errorf("发送消息请求参数错误: %w", err))
		response.Error(c, http.StatusBadRequest, "请求参数错误")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 发送消息
	message, err := h.chatService.SendMessage(
		userID.(uint),
		uint(partnerID),
		req.Content,
		req.Type,
		req.ReplyToID,
		req.FileURL,
		req.FileName,
		req.FileSize,
	)
	if err != nil {
		logger.Error(fmt.Errorf("发送消息失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "发送消息失败")
		return
	}

	response.Success(c, message)
}

// MarkMessagesAsRead 标记消息为已读
func (h *PrivateChatHandler) MarkMessagesAsRead(c *gin.Context) {
	// 获取聊天对象ID
	partnerID, err := strconv.ParseUint(c.Param("partner_id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "用户ID格式错误")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 标记消息为已读
	err = h.chatService.MarkMessagesAsRead(userID.(uint), uint(partnerID))
	if err != nil {
		logger.Error(fmt.Errorf("标记消息为已读失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "标记消息为已读失败")
		return
	}

	response.Success(c, gin.H{"message": "标记成功"})
}

// GetUnreadCount 获取未读消息数量
func (h *PrivateChatHandler) GetUnreadCount(c *gin.Context) {
	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 获取未读消息数量
	count, err := h.chatService.GetUnreadMessageCount(userID.(uint))
	if err != nil {
		logger.Error(fmt.Errorf("获取未读消息数量失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "获取未读消息数量失败")
		return
	}

	response.Success(c, gin.H{"unread_count": count})
}

// GetChatUnreadCount 获取与特定用户的未读消息数量
func (h *PrivateChatHandler) GetChatUnreadCount(c *gin.Context) {
	// 获取聊天对象ID
	partnerID, err := strconv.ParseUint(c.Param("partner_id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "用户ID格式错误")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 获取未读消息数量
	count, err := h.chatService.GetChatUnreadCount(userID.(uint), uint(partnerID))
	if err != nil {
		logger.Error(fmt.Errorf("获取聊天未读消息数量失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "获取聊天未读消息数量失败")
		return
	}

	response.Success(c, gin.H{"unread_count": count})
}

// DeleteChat 删除私聊会话
func (h *PrivateChatHandler) DeleteChat(c *gin.Context) {
	// 获取聊天对象ID
	partnerID, err := strconv.ParseUint(c.Param("partner_id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "用户ID格式错误")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 删除私聊会话
	err = h.chatService.DeleteChat(userID.(uint), uint(partnerID))
	if err != nil {
		logger.Error(fmt.Errorf("删除私聊会话失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "删除私聊会话失败")
		return
	}

	response.Success(c, gin.H{"message": "删除成功"})
}

// SearchUsers 搜索用户（用于聊天）
func (h *PrivateChatHandler) SearchUsers(c *gin.Context) {
	keyword := c.Query("keyword")
	if keyword == "" {
		response.Error(c, http.StatusBadRequest, "搜索关键词不能为空")
		return
	}

	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 搜索用户
	users, err := h.chatService.SearchUsers(keyword, userID.(uint))
	if err != nil {
		logger.Error(fmt.Errorf("搜索用户失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "搜索用户失败")
		return
	}

	response.Success(c, users)
}

// GetOnlineUsers 获取在线用户列表
func (h *PrivateChatHandler) GetOnlineUsers(c *gin.Context) {
	// 获取当前用户信息
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, http.StatusUnauthorized, "未认证")
		return
	}

	// 获取在线用户
	users, err := h.chatService.GetOnlineUsers(userID.(uint))
	if err != nil {
		logger.Error(fmt.Errorf("获取在线用户失败: %w", err))
		response.Error(c, http.StatusInternalServerError, "获取在线用户失败")
		return
	}

	response.Success(c, users)
}

// 兼容前端API的适配器方法

// GetMessagesForChatAPI 兼容前端的获取消息接口
func (h *PrivateChatHandler) GetMessagesForChatAPI(c *gin.Context) {
	// 前端传递的是 other_user_id 参数
	otherUserID := c.Query("other_user_id")
	if otherUserID == "" {
		response.Error(c, http.StatusBadRequest, "缺少other_user_id参数")
		return
	}

	// 将请求转发到原有的GetMessages方法
	c.Params = append(c.Params, gin.Param{Key: "partner_id", Value: otherUserID})
	h.GetMessages(c)
}

// SendMessageForChatAPI 兼容前端的发送消息接口
func (h *PrivateChatHandler) SendMessageForChatAPI(c *gin.Context) {
	// 前端传递的是 receiver_id 参数
	receiverID := c.Query("receiver_id")
	if receiverID == "" {
		// 尝试从请求体中获取
		var reqBody map[string]interface{}
		if err := c.ShouldBindJSON(&reqBody); err == nil {
			if rid, ok := reqBody["receiver_id"]; ok {
				receiverID = fmt.Sprintf("%v", rid)
			}
		}
	}

	if receiverID == "" {
		response.Error(c, http.StatusBadRequest, "缺少receiver_id参数")
		return
	}

	// 将请求转发到原有的SendMessage方法
	c.Params = append(c.Params, gin.Param{Key: "partner_id", Value: receiverID})
	h.SendMessage(c)
}

// MarkMessagesAsReadForChatAPI 兼容前端的标记已读接口
func (h *PrivateChatHandler) MarkMessagesAsReadForChatAPI(c *gin.Context) {
	// 前端传递的是 user_id 参数
	userID := c.Param("user_id")
	if userID == "" {
		response.Error(c, http.StatusBadRequest, "缺少user_id参数")
		return
	}

	// 将请求转发到原有的MarkMessagesAsRead方法
	c.Params = append(c.Params, gin.Param{Key: "partner_id", Value: userID})
	h.MarkMessagesAsRead(c)
}
